package com.zhs.type;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.zhs.javacc.SimpleNode;

public class Method {

	/**
	 * where this method belongs
	 */
	private String hostTypeName;
	private String methodName;
	private ArrayList<Variable> parameters = new ArrayList<Variable>();
	private Scope scope = new Scope();
	private List<Statement> statements = new ArrayList<Statement>();
	private List<SimpleNode> statementNode = new ArrayList<SimpleNode>();
	private String returnTypeName;
	private SimpleNode returnNode;
	private List<Variable> declaredVariables = new ArrayList<Variable>();

	public List<Variable> getDeclaredVariables() {
		return declaredVariables;
	}

	public SimpleNode getReturnNode() {
		return returnNode;
	}

	public void setReturnNode(SimpleNode returnNode) {
		this.returnNode = returnNode;
	}

	public void addStatementNode(SimpleNode node) {
		this.statementNode.add(node);
	}

	public List<SimpleNode> getStatementNodes() {
		return statementNode;
	}

	public String getReturnTypeName() {
		return returnTypeName;
	}

	public void setReturnTypeName(String returnTypeName) {
		this.returnTypeName = returnTypeName;
	}

	public String getHostTypeName() {
		return hostTypeName;
	}

	public void setHostTypeName(String type) {
		this.hostTypeName = type;
	}

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public List<Statement> getStatements() {
		return statements;
	}

	public void setStatements(List<Statement> statements) {
		this.statements = statements;
	}

	public Collection<Variable> getParameters() {
		return parameters;
	}

	public Scope getScope() {
		Scope result = scope.clone();
		result.addScope(parameters);
		return result;
	}

	public void setScope(Scope scope) {
		this.scope = scope;
	}

	public Variable addParameter(Variable var) {
		if (!this.parameters.contains(var)) {
			this.parameters.add(var);
			return null;
		} else
			return var;
	}

	public void setParentScope(Scope parent) {
		this.scope.setParent(parent);
	}

	public Variable lookupVariable(String varName) {
		for (Variable v : parameters) {
			if (v.getVarName().equals(varName)) {
				return v;
			}
		}

		return scope.lookupVariable(varName);
	}

	public Variable addVariableToScope(Variable var) {
		if (this.scope.addVariable(var) == null) {
			this.declaredVariables.add(var);
			return null;
		} else {
			return this.scope.lookupVariable(var.getVarName());
		}
	}
}
